home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 November / Macworld (1999-11).dmg / Updaters / WhiteCap 3.0.4 / WhiteCap Source.sit / WhiteCap Source / Common / General Tools / XList.cpp < prev    next >
C/C++ Source or Header  |  1999-07-13  |  4KB  |  209 lines

  1. #include "XList.h"
  2.  
  3.  
  4.  
  5. XList::XList( nodeClass* inParent ) :
  6.     nodeClass( inParent ) {
  7.     
  8.     mCachedNode = NULL;
  9. }
  10.  
  11.  
  12.  
  13.  
  14. void XList::UpdateCounts( int inShallowChange ) {
  15.     
  16.     nodeClass::UpdateCounts( inShallowChange );
  17.     
  18.     mCachedNode = NULL;
  19. }    
  20.  
  21.  
  22.  
  23. nodeClass* XList::findSubNode( long inNum ) {
  24.     nodeClass*        retPtr = NULL;
  25.     long            i;
  26.     
  27.     if ( mCachedNode ) {                                //    Check cached node...
  28.         i = inNum - mCachedNodeNum;                        //    See how far away our cached node is
  29.         
  30.         if ( i > -4 && i < 4 ) {
  31.             retPtr = mCachedNode;
  32.             if ( i < 0 ) {                                //     The cached node was after the desired
  33.                 for ( ; i != 0 && retPtr; i++ )            //    Move forward the num that the cache is off
  34.                     retPtr = retPtr -> PrevInChain( this );    }
  35.             else {
  36.                 for ( ; i != 0 && retPtr; i-- )
  37.                     retPtr = retPtr -> NextInChain( this ); 
  38.             }
  39.         }
  40.         
  41.         #ifdef EG_DEBUG
  42.         if ( retPtr )
  43.             sCacheHitsA++;
  44.         sCacheTrysA++;
  45.         #endif
  46.     }            
  47.     
  48.     if ( ! retPtr )                                     // If no cache his was found
  49.         retPtr = nodeClass::findSubNode( inNum );        // Do it by brute force
  50.     
  51.     if ( retPtr ) {
  52.         mCachedNodeNum    = inNum;
  53.         mCachedNode        = retPtr;
  54.     }
  55.     
  56.     return retPtr;
  57. }
  58.  
  59.  
  60.  
  61. long XList::findSubNode( nodeClass* inNodePtr ) {
  62.     nodeClass*        nodePtr;
  63.     long            n = 0;
  64.     
  65.     if ( mCachedNode && inNodePtr ) {                    // If we have a cache available
  66.         if ( mCachedNode == inNodePtr )                    //    Check trivial cache case
  67.             n = mCachedNodeNum;
  68.             
  69.         if ( n == 0 ) {                                    // If no hit yet...
  70.             nodePtr = mCachedNode -> NextInChain( this );
  71.             if ( nodePtr == inNodePtr )                    // Check node after cached node
  72.                 n = mCachedNodeNum + 1;
  73.         }
  74.         
  75.         if ( n == 0 ) {                                    // If no hit yet...
  76.             nodePtr = mCachedNode -> PrevInChain( this );
  77.             if ( nodePtr == inNodePtr )                    // Check node before cached node
  78.                 n = mCachedNodeNum - 1;
  79.         }
  80.         
  81.         #ifdef EG_DEBUG
  82.         if ( n > 0 )
  83.             sCacheHitsB++;
  84.         sCacheTrysB++;
  85.         #endif
  86.     }
  87.     
  88.     if ( n == 0 )                                         // If no cache hit...
  89.         n = nodeClass::findSubNode( inNodePtr );        // Do it with brute force.
  90.     
  91.     if ( n > 0 ) {                                        // Update the cache if possible...
  92.         mCachedNode        = inNodePtr;
  93.         mCachedNodeNum    = n;
  94.     }
  95.         
  96.     return n;
  97. }
  98.  
  99.  
  100.  
  101. long XList::GetParent( long inCellNum ) {
  102.     nodeClass* nodePtr = findSubNode( inCellNum );
  103.     
  104.     if ( nodePtr ) {
  105.         if ( nodePtr -> GetParent() == this )
  106.             return 0;
  107.         else
  108.             return findSubNode( nodePtr -> GetParent() ); }
  109.     else
  110.         return -1;
  111. }
  112.  
  113.  
  114.         
  115. XLongList* XList::ManageClick( long inCell, bool inShift, bool inCmd, bool inDeselectRest ) {
  116.     XLongList*    retPtr    = ListSocket::ManageClick( inCell, inShift, inCmd, inDeselectRest );
  117.     nodeClass*    nodePtr    = GetDeepTail();
  118.     long        i        = deepCount();
  119.     
  120.     while ( nodePtr ) {
  121.         if ( nodePtr -> IsSelected() ) {
  122.             SetInsertionPt( i, nodePtr -> CountDepth( this ) - 1 );
  123.             return retPtr;
  124.         }
  125.         
  126.         i--;
  127.         nodePtr = nodePtr -> PrevInChain( this );
  128.     }
  129.     
  130.     return retPtr;
  131. }
  132.  
  133.  
  134.  
  135. void XList::DoBestInsert( nodeClass* inNodeToAdd ) {
  136.     nodeClass*    insertPt = findSubNode( mInsertionPt );
  137.     long        insDepth;
  138.     
  139.     if ( inNodeToAdd ) {
  140.         if ( insertPt ) {
  141.             insDepth = insertPt -> CountDepth( this ) - 1;
  142.             while ( insDepth > mInsertionDepth && insertPt ) {
  143.                 insertPt = insertPt -> GetParent();
  144.                 insDepth--;
  145.                 
  146.                 if ( insertPt == this )
  147.                     insertPt = NULL;
  148.             }
  149.         }
  150.         
  151.         if ( insertPt ) {    
  152.             if ( insDepth == mInsertionDepth )
  153.                 inNodeToAdd -> insertAfter( insertPt );
  154.             else //  depth < inDepth
  155.                 insertPt -> addToHead( inNodeToAdd ); }
  156.         else {
  157.             if ( mInsertionPt <= 0 ) 
  158.                 addToHead( inNodeToAdd );
  159.             else 
  160.                 addToTail( inNodeToAdd );
  161.         }
  162.         
  163.         mInsertionPt    = findSubNode( inNodeToAdd );
  164.         mInsertionDepth    = inNodeToAdd -> CountDepth( this ) - 1;
  165.     }
  166. }
  167.  
  168.  
  169. void XList::SetInsertPtBefore( nodeClass* inInsertPt ) {
  170.     long n = findSubNode( inInsertPt );
  171.  
  172.     if ( n <= 0 )
  173.         inInsertPt = GetDeepTail();
  174.     else if ( n == 1 ) 
  175.         inInsertPt = NULL;
  176.     else 
  177.         inInsertPt = inInsertPt -> PrevInChain( this ); 
  178.                     
  179.     if ( inInsertPt )
  180.         SetInsertionPt( findSubNode( inInsertPt ), inInsertPt -> CountDepth( this ) - 1 );
  181.     else
  182.         SetInsertionPt( 0, 0 );
  183.  
  184. }
  185.  
  186.  
  187.  
  188. void XList::SetSelected( long inElementNum, bool isSelected ) {
  189.     nodeClass*    nodePtr = findSubNode( inElementNum );
  190.  
  191.     if ( nodePtr )
  192.         nodePtr -> SetSelected( isSelected );
  193. }
  194.  
  195.  
  196. bool XList::IsSelected( long inElementNum ) {
  197.     nodeClass*    nodePtr = findSubNode( inElementNum );
  198.         
  199.     if ( nodePtr )
  200.         return nodePtr -> IsSelected();
  201.     else
  202.         return false;
  203. }
  204.  
  205.  
  206.  
  207. long XList::NumCells() {
  208.     return deepCount();
  209. }